package com.niiwoo.civet.user.service.local;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.asset.constant.MqConstants;
import com.niiwoo.asset.dto.mq.UserCreditResultDTO;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.user.dao.aggregation.CreditDeviceInfo;
import com.niiwoo.civet.user.dao.entity.*;
import com.niiwoo.civet.user.dao.mapper.UserCreditCardAuthInfoMapperExt;
import com.niiwoo.civet.user.dao.mapper.UserCreditInfoMapperExt;
import com.niiwoo.civet.user.dao.mapper.UserCreditProcessMapperExt;
import com.niiwoo.civet.user.dto.request.AppButtonDTO;
import com.niiwoo.civet.user.dto.request.UserLetterRequestDTO;
import com.niiwoo.civet.user.dto.response.UserCreditDataStatusDTO;
import com.niiwoo.civet.user.enums.*;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import com.niiwoo.tripod.tiancheng.component.TianchengAgainstFakeService;
import com.niiwoo.tripod.tiancheng.component.TianchengDataFlowService;
import com.niiwoo.tripod.tiancheng.enums.FunctionCodeEnum;
import com.niiwoo.tripod.tiancheng.enums.ModleResultEnum;
import com.niiwoo.tripod.tiancheng.request.afp.LoanAmountAgainsFakeRequest;
import com.niiwoo.tripod.tiancheng.request.df.CreditDataFlowRequest;
import com.niiwoo.tripod.tiancheng.response.common.AgainstFakeResponse;
import com.niiwoo.tripod.tiancheng.response.common.TianchengUapResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @Author:LiJian
 * @Date:2017/11/7
 */
@Slf4j
@Service
public class UserCreditService {

    // 天秤授信反欺诈回调地址模型(AFP)
    public static final String TIANCHENG_AFP_CALLBACK_URL = "%s/tc/againstFake/callback?functionCode=%s";

    // 天秤授信授信回调地址模型(AFP)
    public static final String TIANCHENG_AFP_CREDIT_CALLBACK_URL = "%s/tc/credit/callback?functionCode=%s";

    @Value(value = "${web-http-url}")
    private String webHttpUrl;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    private UserCreditInfoMapperExt userCreditInfoMapper;

    @Autowired
    private UserCreditProcessMapperExt userCreditProcessMapper;

    @Autowired
    private TianchengAgainstFakeService againstFakeService;

    @Autowired
    private TianchengDataFlowService dataFlowService;

    @Autowired
    private UserStatusService userStatusLocalService;

    @Autowired
    private UserIdentityService userIdentityService;

    @Autowired
    private UserLetterService userLetterService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Reference(version = "1.0.0")
    private TradeConfigDubboService tradeConfigDubboService;

    @Autowired
    UserCreditCardAuthInfoMapperExt userCreditCardAuthInfoMapper;

    @Autowired
    UserStatusService userStatusService;

    /**
     * 根据类型获取用户授信额度
     * @param userId
     * @param creditType
     * @return
     */
    public UserCreditInfo getUserCreditInfoByType(String userId, Byte creditType) {
        UserCreditInfo creditInfo = userCreditInfoMapper.selectByUserIdAndType(userId, creditType);

        return creditInfo;
    }

    /**
     * 根据类型获取用户授信过程信息
     * @param userId
     * @param creditType
     * @return
     */
    public UserCreditProcess getUserCreditProcessByType(String userId, Byte creditType) {
        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }

        UserCreditProcess userCreditProcess = userCreditProcessMapper.selectByUserAndType(userId, creditType);

        return userCreditProcess;
    }

    /**
     * 更新用户授信信息
     * @param userCreditInfo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateUserCreditInfo(UserCreditInfo userCreditInfo) {
        int updateNum = userCreditInfoMapper.updateByUserIdAndType(userCreditInfo);
        if(updateNum < 1) {
            userCreditInfo.setId(snowflakeIdWorker.nextId());
            userCreditInfo.setCreateTime(new Date());
            updateNum = userCreditInfoMapper.insertSelective(userCreditInfo);
        }
        return updateNum;
    }

    /**
     * 修改授信过程状态
     * @param userCreditProcess
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int updateUserCreditProcess(UserCreditProcess userCreditProcess) {
        int updateNum = userCreditProcessMapper.updateByUserAndType(userCreditProcess);
        if(updateNum < 1) {
            Date currDate = new Date();
            userCreditProcess.setId(snowflakeIdWorker.nextId());
            userCreditProcess.setCreditStartTime(currDate);
            userCreditProcess.setCreditEndTime(currDate);
            userCreditProcess.setCreateTime(new Date());
            updateNum = userCreditProcessMapper.insertSelective(userCreditProcess);
        }
        return updateNum;
    }

    /**
     * 获取用户授信资料状态
     * @param userId
     * @param operatorExpire 运营商过期时间
     * @param socialSecurityExpire 社保过期时间
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public UserCreditDataStatusDTO getUserCreditDataStatus(String userId, Integer operatorExpire, Integer socialSecurityExpire, Integer creditcardExpiry) {
        UserCreditDataStatusDTO userCreditDataStatusDTO = new UserCreditDataStatusDTO();
        // 初始化状态
        userCreditDataStatusDTO.setPersonInfoStatus(UserDataStatusEnum.PersonInfoStatus.NOFILL.getStatus());
        userCreditDataStatusDTO.setOCRStatus(UserDataStatusEnum.OCRStatus.NOT_OCR.getStatus());
        userCreditDataStatusDTO.setRealNameAuthStatus(UserDataStatusEnum.RealNameAuthStatus.NOT_CERTIFIED.getStatus());
        userCreditDataStatusDTO.setIdCardStatus(UserDataStatusEnum.IdCardExpiredStatus.VALID.getStatus());
        userCreditDataStatusDTO.setPortraitAuthStatus(UserDataStatusEnum.PortraitAuthStatus.NOT_CERTIFIED.getStatus());
        userCreditDataStatusDTO.setOpenBankAccountStatus(UserDataStatusEnum.OpenBankAccountStatus.NOT_BIND.getStatus());
        userCreditDataStatusDTO.setZhimaCreditStatus(UserDataStatusEnum.ZhimaCreditStatus.NOAPPLY.getStatus());
        userCreditDataStatusDTO.setPhoneOperatorStatus(UserDataStatusEnum.PhoneOperatorStatus.NOCREDIT.getStatus());
        userCreditDataStatusDTO.setSocialSecurityStatus(UserDataStatusEnum.SocialSecurityStatus.NOCREDIT.getStatus());
        userCreditDataStatusDTO.setImgUploadStatus(UserDataStatusEnum.HandPhotoStatus.NO_UPLOAD.getStatus());
        userCreditDataStatusDTO.setCreditCardStatus(UserDataStatusEnum.CreditCardStatus.NOCREDIT.getStatus());

        List<DataStatus> ucDataStatuseList = userStatusLocalService.getDataStatusByUserId(userId);
        for (DataStatus dataStatus : ucDataStatuseList) {
            byte dataStatusByte = dataStatus.getDataStatus().byteValue();
            byte dataTypeByte = dataStatus.getDataType().byteValue();
            if (UserDataTypeEnum.PERSONAL_INFO.getValue() == dataTypeByte) {
                userCreditDataStatusDTO.setPersonInfoStatus(dataStatusByte);
            } else if (UserDataTypeEnum.TWO_ELEMENT.getValue() == dataTypeByte) {
                userCreditDataStatusDTO.setRealNameAuthStatus(dataStatusByte);
            } else if (UserDataTypeEnum.OCR.getValue() == dataStatus.getDataType().byteValue()) {
                userCreditDataStatusDTO.setOCRStatus(dataStatusByte);
//            } else if (UserDataTypeEnum.BIND_BANK_CARD.getValue() == dataTypeByte) {
//                userCreditDataStatusDTO.setOpenBankAccountStatus(dataStatusByte);
            } else if (UserDataTypeEnum.PORTRAIT.getValue() == dataTypeByte) {
                userCreditDataStatusDTO.setPortraitAuthStatus(dataStatusByte);
            } else if (UserDataTypeEnum.ZHIMA_AUTHORIZE.getValue() == dataTypeByte) {
                userCreditDataStatusDTO.setZhimaCreditStatus(dataStatusByte);
            } else if (UserDataTypeEnum.OPERATOR_AUTHORIZE.getValue() == dataTypeByte) {
                if (UserDataStatusEnum.PhoneOperatorStatus.GETFAIL.getStatus() != dataStatusByte) {
                    userCreditDataStatusDTO.setPhoneOperatorStatus(dataStatusByte);
                }
                // 判断运营商过期时间
                if(UserDataStatusEnum.PhoneOperatorStatus.GETSUCCESS.getStatus() == dataStatusByte) {
                    DateTime authTime = new DateTime(dataStatus.getAuthTime());
                    if(operatorExpire != null && authTime.plusDays(operatorExpire).isBeforeNow()) {
                        DataStatus ds = new DataStatus();
                        ds.setUserId(userId);
                        ds.setDataType(UserDataTypeEnum.OPERATOR_AUTHORIZE.getValue());
                        ds.setDataStatus(UserDataStatusEnum.PhoneOperatorStatus.EXPIRED.getStatus());
                        ds.setAuthTime(new Date());
                        userStatusLocalService.updateDataStatusByUserIdAndType(ds);
                        userCreditDataStatusDTO.setPhoneOperatorStatus(UserDataStatusEnum.PhoneOperatorStatus.EXPIRED.getStatus());
                    }
                }

                //已验证状态，如果超过设置的时间，修改授权状态为失败，让用户可以重新授权
                if(UserDataStatusEnum.PhoneOperatorStatus.ALREADY_CREDIT.getStatus().equals(dataStatus.getDataStatus())){
                    //获取数据库中指定的时长
                    List<TradeConfigEnum> list = new ArrayList<>();
                    //由于超过时间后前台点击就会修改状态为失败，为了保证用户正常收到提醒信息，
                    //这里自动修改状态的时间由发送提醒时间（SPEEDBORROWNOCRSENDMSGAFTERMAXMIN），
                    //修改为自动退回标的时间（SPEEDBORROWNOCRBIDPROJECTAFTERMAXMIN）（加长）
                    list.add(TradeConfigEnum.SPEEDBORROWNOCRBIDPROJECTAFTERMAXMIN);
                    Map<String, String> configMap = tradeConfigDubboService.selectTradeConfigByEmuns(list);
                    if (configMap != null && dataStatus.getAuthTime() != null) {
                        int minute = NumberUtils.toInt(configMap.get(TradeConfigEnum.SPEEDBORROWNOCRBIDPROJECTAFTERMAXMIN.getConfigKey()));
                        if(minute > 0){
                            Date paramDate = DateUtils.addMinutes(dataStatus.getAuthTime(), minute);
                            if(paramDate.getTime() < System.currentTimeMillis()){
                                //超过设置的时间，修改状态为失败，让用户可以重新授权
                                dataStatus.setDataStatus(UserDataStatusEnum.PhoneOperatorStatus.GETFAIL.getStatus());
                                dataStatus.setUpdateTime(new Date());
                                userStatusLocalService.updateDataStatusByUserIdAndType(dataStatus);
                                userCreditDataStatusDTO.setPhoneOperatorStatus(UserDataStatusEnum.PhoneOperatorStatus.GETFAIL.getStatus());
                            }
                        }
                    }
                }

            } else if (UserDataTypeEnum.SOCIAL_SECURITY_OPERATOR_AUTHORIZE.getValue() == dataTypeByte) {
                if (UserDataStatusEnum.SocialSecurityStatus.GETFAIL.getStatus() != dataStatusByte
                        &&UserDataStatusEnum.SocialSecurityStatus.DIFFER.getStatus() != dataStatusByte) {
                    userCreditDataStatusDTO.setSocialSecurityStatus(dataStatusByte);
                }
                // 判断社保过期时间
                if(UserDataStatusEnum.SocialSecurityStatus.GETSUCCESS.getStatus() == dataStatusByte) {
                    DateTime authTime = new DateTime(dataStatus.getAuthTime());
                    if(socialSecurityExpire != null && authTime.plusDays(socialSecurityExpire).isBeforeNow()) {
                        DataStatus ds = new DataStatus();
                        ds.setUserId(userId);
                        ds.setDataType(UserDataTypeEnum.SOCIAL_SECURITY_OPERATOR_AUTHORIZE.getValue());
                        ds.setDataStatus(UserDataStatusEnum.SocialSecurityStatus.EXPIRED.getStatus());
                        ds.setAuthTime(new Date());
                        userStatusLocalService.updateDataStatusByUserIdAndType(ds);
                        userCreditDataStatusDTO.setSocialSecurityStatus(UserDataStatusEnum.SocialSecurityStatus.EXPIRED.getStatus());
                    }
                }
            } else if (UserDataTypeEnum.CREDIT_CARD_AUTHORIZE.getValue() == dataTypeByte) {
                if (UserDataStatusEnum.CreditCardStatus.GETFAIL.getStatus() != dataStatusByte) {
                    userCreditDataStatusDTO.setCreditCardStatus(dataStatusByte);
                }
                // 判断信用卡过期时间
                if(UserDataStatusEnum.CreditCardStatus.GETSUCCESS.getStatus() == dataStatusByte) {
                    DateTime authTime = new DateTime(dataStatus.getAuthTime());
                    if(creditcardExpiry != null && authTime.plusDays(creditcardExpiry).isBeforeNow()) {
                        DataStatus ds = new DataStatus();
                        ds.setUserId(userId);
                        ds.setDataType(UserDataTypeEnum.CREDIT_CARD_AUTHORIZE.getValue());
                        ds.setDataStatus(UserDataStatusEnum.CreditCardStatus.EXPIRED.getStatus());
                        ds.setAuthTime(new Date());
                        userStatusLocalService.updateDataStatusByUserIdAndType(ds);
                        userCreditDataStatusDTO.setCreditCardStatus(UserDataStatusEnum.CreditCardStatus.EXPIRED.getStatus());
                    }
                }
            }
        }
        // 已OCR且二要素通过才进行身份证有效期判断
        if(userCreditDataStatusDTO.getOCRStatus() == UserDataStatusEnum.OCRStatus.YES_OCR.getStatus().byteValue() &&
                userCreditDataStatusDTO.getRealNameAuthStatus() == UserDataStatusEnum.RealNameAuthStatus.PASS_CERTIFIED.getStatus().byteValue()) {
            IdentityInfo identityInfo = userIdentityService.getByUserId(userId);
            Date idcardExpired = identityInfo.getEndDate();
            if(idcardExpired != null) {
                DateTime idcardExpiredTime = new DateTime(idcardExpired);
                if(idcardExpiredTime.isBeforeNow()) {
                    userCreditDataStatusDTO.setIdCardStatus(UserDataStatusEnum.IdCardExpiredStatus.EXPIRED.getStatus());
                }else if(idcardExpiredTime.minusDays(30).isBeforeNow()) {
                    // 身份证有效期距离有效期截止日期30天以内,则为快过期
                    userCreditDataStatusDTO.setIdCardStatus(UserDataStatusEnum.IdCardExpiredStatus.EXPIRING.getStatus());
                }
            }
        }
        return userCreditDataStatusDTO;
    }


    /**
     * 本地发起极速借授信反欺诈
     * @param userId
     * @param source
     * @param againstFakeResult 反欺诈请求结果
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean localLaunchSpeedLoanCredit(String userId, Integer source, CreditDeviceInfo creditDeviceInfo, boolean againstFakeResult) {
        Date currDate = new Date();
        UserCreditProcess userCreditProcess = new UserCreditProcess();
        userCreditProcess.setUserId(userId);
        userCreditProcess.setCreditCaller(source.byteValue());
        userCreditProcess.setCreditType(CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.UNVERIFIED.getType());
        userCreditProcess.setDeviceInfo(creditDeviceInfo != null ? JSON.toJSONString(creditDeviceInfo) : null);
        userCreditProcess.setCreditStartTime(currDate);
        userCreditProcess.setCreditEndTime(currDate);
        if(againstFakeResult) {
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.CALLBACKING.getType());
            this.updateUserCreditProcess(userCreditProcess);
            return true;
        }else {
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.FAIL.getType());
            userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.UNVERIFIED.getType());
            this.updateUserCreditProcess(userCreditProcess);
            return false;
        }
    }

    /**
     * 发起天秤极速借授信反欺诈
     * @param userId
     * @param zhimaSwitch 芝麻开关
     * @param request
     * @return
     */
    public AgainstFakeResponse callTCSpeedCreditAgainstFakeAFP(String userId, String zhimaSwitch, LoanAmountAgainsFakeRequest request) {
        log.info("发起天秤极速借授信发欺诈, userId:{}, params:{}", userId, JSON.toJSONString(request));
        AgainstFakeResponse againstFakeResponse = null;
        try {
            // 区分芝麻开关所用模型
            CompletableFuture<AgainstFakeResponse> responseCompletableFuture = "1".equals(zhimaSwitch) ?
                    againstFakeService.getLoanCreditAmountAgainstFake(request) : againstFakeService.getNoZhimaLoanCreditAmountAgainstFake(request);
            againstFakeResponse = responseCompletableFuture.get(10, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("发起天秤极速借授信发欺诈失败, userId:{}, params:{}, errMsg:{}", userId, JSON.toJSONString(request), e);
            return againstFakeResponse;
        }
        if(!ModleResultEnum.ACCEPT.getModelResult().equals(againstFakeResponse.getStatus())) {
            log.error("天秤极速借授信发欺诈返回失败, userId:{}, params:{}, result:{}", userId, JSON.toJSONString(request), JSON.toJSONString(againstFakeResponse));
            return againstFakeResponse;
        }
        return againstFakeResponse;
    }

    /**
     * 发起天秤极速借授信数据回流
     * @param userId
     * @param request
     * @return
     */
    public TianchengUapResponse callTCCreditFlowData(String userId, CreditDataFlowRequest request) {
        // 加入请求反欺诈时候的设备信息
        UserCreditProcess userCreditProcess = this.getUserCreditProcessByType(userId, CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        if(StringUtils.isNotBlank(userCreditProcess.getDeviceInfo())) {
            CreditDeviceInfo deviceInfo = JSON.parseObject(userCreditProcess.getDeviceInfo(), CreditDeviceInfo.class);
            CreditDataFlowRequest.DeviceInfo flowDeviceInfo = new  CreditDataFlowRequest.DeviceInfo();
            BeanUtils.copyProperties(deviceInfo, flowDeviceInfo);
            request.setDeviceInfo(flowDeviceInfo);
        }
        this.initCreditCardInfo(userId,request);
        log.info("发起天秤极速借授信, userId:{}, params:{}", userId, JSON.toJSONString(request));
        TianchengUapResponse tianchengUapResponse = null;
        try {
            CompletableFuture<TianchengUapResponse>  uapResponseCompletableFuture = dataFlowService.creditDataFlow(request);
            tianchengUapResponse = uapResponseCompletableFuture.get();
        } catch (Exception e) {
            log.error("发起天秤极速借授信失败, userId:{}, params:{}, errMsg:{}", userId, JSON.toJSONString(request), e);
            return tianchengUapResponse;
        }
        if(tianchengUapResponse == null || !ModleResultEnum.ACCEPT.getModelResult().equals(tianchengUapResponse.getStatus())) {
            log.error("天秤极速借授信失败返回失败, userId:{}, params:{}, result:{}", userId, JSON.toJSONString(request), JSON.toJSONString(tianchengUapResponse));
            return tianchengUapResponse;
        }
        return tianchengUapResponse;

    }

    private void initCreditCardInfo(String userId, CreditDataFlowRequest request){
        try {
            DataStatus dataStatus = userStatusService.getByUserIdAndType(userId, UserDataTypeEnum.CREDIT_CARD_AUTHORIZE);

            if(dataStatus==null){
                log.info("initCreditCardInfo.dataStatus为空,userId={}",userId);
                return;
            }
            byte dataStatusValue = dataStatus.getDataStatus().byteValue();
            CreditDataFlowRequest.UserBasicInfo userBasicInfo = request.getUserBasicInfo();
            if(UserDataStatusEnum.CreditCardStatus.ALREADY_CREDIT.getStatus().byteValue()==dataStatusValue
                    || UserDataStatusEnum.CreditCardStatus.GETSUCCESS.getStatus().byteValue()==dataStatusValue) {
                userBasicInfo.setCreditAuthStatus(1); //0 信用卡未授权，1信用卡已授权
            }else{
                userBasicInfo.setCreditAuthStatus(0);
            }

            UserCreditCardAuthInfo userCreditCardAuthInfo = userCreditCardAuthInfoMapper.selectByPrimaryKey(userId);
            if(userCreditCardAuthInfo==null){
                log.info("initCreditCardInfo.userCreditCardAuthInfo为空,userId={}",userId);
                return;
            }
            request.setLoginName(userCreditCardAuthInfo.getLoginName());
            request.setEntryId(userCreditCardAuthInfo.getEntryId());
        } catch (Exception e) {
            log.error("initCreditCardInfo异常,userId={}",userId,e);
        }
    }

    /**
     * 极速借反欺诈回调本地处理
     * @param userId
     * @param modelResult 模型结果
     * @param creditFlowStatus 授信模型数据回流状态
     * @param platformType 平台类型
     */
    @Transactional(rollbackFor = Exception.class)
    public void creditAgainstFakeLocalHandle(String userId, String modelResult, boolean creditFlowStatus, int platformType) {
        log.info("creditAgainstFakeLocalHandle, userId={}, modelResult={}, creditFlowStatus={}, platformType={}", userId, modelResult, creditFlowStatus, platformType);
        UserCreditProcess userCreditProcess = new UserCreditProcess();
        userCreditProcess.setUserId(userId);
        userCreditProcess.setCreditType(CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        if(ModleResultEnum.ACCEPT.getModelResult().equals(modelResult)) {
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.ACCEPT.getType());
            if(creditFlowStatus) {
                userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.CALLBACKING.getType());
            }else {
                userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.FAIL.getType());
                userCreditProcess.setCreditEndTime(new Date());
            }
        }else if(ModleResultEnum.REVIEW.getModelResult().equals(modelResult)) {
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.REVIEW.getType());
            if(creditFlowStatus) {
                userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.CALLBACKING.getType());
            }else {
                userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.FAIL.getType());
                userCreditProcess.setCreditEndTime(new Date());
            }
        }else if(ModleResultEnum.REFUSE.getModelResult().equals(modelResult)) {
            userCreditProcess.setCreditEndTime(new Date());
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.REFUSE.getType());
        }else {
            userCreditProcess.setCreditEndTime(new Date());
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.FAIL.getType());
        }
        // 修改授信反欺诈及授信过程状态
        this.updateUserCreditProcess(userCreditProcess);

        // 融360回流通知
        if (PlatformTypeEnum.RONG360.getType() == platformType) {
            UserCreditResultDTO userCreditResultDTO = new UserCreditResultDTO();

            userCreditResultDTO.setUserId(userId);
            userCreditResultDTO.setPlatformType(PlatformTypeEnum.RONG360.getType());
            userCreditResultDTO.setResultType(UserCreditResultDTO.ResultTypeEnum.CREDIT_FRAUD_RESULT.getType());

            rabbitTemplate.convertAndSend(MqConstants.Exchange.ASSET_EXCHANGE, MqConstants.getRoutingKey(MqConstants.Exchange.ASSET_EXCHANGE, MqConstants.Queue.CREDIT_RESULT), userCreditResultDTO);
            log.info("融360授信发欺诈通知：{}", JSON.toJSONString(userCreditResultDTO));
        }
    }

    /**
     * 授信回调处理
     * @param userId
     * @param creditAmount
     * @param fastBorrowType 极速借借款类型（0：信用评分不足，不能借款、1：社保、2：芝麻、3：学历）
     */
    @Transactional(rollbackFor = Exception.class)
    public void speedLoanCreditLocalHandle(String userId, BigDecimal creditAmount, Integer fastBorrowType, boolean creditStatus) {
        Date currDate = new Date();
        UserCreditProcess userCreditProcess = new UserCreditProcess();
        userCreditProcess.setUserId(userId);
        userCreditProcess.setCreditType(CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.ACCEPT.getType());
        userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.SUCCESS.getType());
//        if(!creditStatus) {
//            userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.FAIL.getType());
//        }
        userCreditProcess.setCreditEndTime(currDate);
        // 修改授信反欺诈及授信过程状态
        this.updateUserCreditProcess(userCreditProcess);


        // 修改授信额度信息
        if(fastBorrowType != null) {
            UserCreditInfo userCreditInfo = new UserCreditInfo();
            userCreditInfo.setUserId(userId);
            userCreditInfo.setCreditType(CreditEnum.CreditAmountType.SPEED_BORROW.getType());
            userCreditInfo.setCreditModelType(fastBorrowType.byteValue());
            userCreditInfo.setCreditAmount(creditAmount);
            userCreditInfo.setNeedUpdate(CreditEnum.NeedUpdateStatus.NO.getType());
            userCreditInfo.setCreditTime(currDate);
            this.updateUserCreditInfo(userCreditInfo);
        }

        // 融360回调MQ通知
        if (CreditEnum.CreditModelType.RONG360.getType() == fastBorrowType.byteValue() || CreditEnum.CreditModelType.RONG360_FREE_QUALIFICATION.getType() == fastBorrowType.byteValue()) {
            UserCreditResultDTO userCreditResultDTO = new UserCreditResultDTO();

            userCreditResultDTO.setUserId(userId);
            userCreditResultDTO.setPlatformType(PlatformTypeEnum.RONG360.getType());
            userCreditResultDTO.setResultType(UserCreditResultDTO.ResultTypeEnum.CREDIT_RESULT.getType());

            rabbitTemplate.convertAndSend(MqConstants.Exchange.ASSET_EXCHANGE, MqConstants.getRoutingKey(MqConstants.Exchange.ASSET_EXCHANGE, MqConstants.Queue.CREDIT_RESULT), userCreditResultDTO);
            log.info("融360授信结果通知：{}", JSON.toJSONString(userCreditResultDTO));
        }
    }

    /**
     * 创建天秤AFP回调地址
     * @param functionCodeEnum
     * @return
     */
    public String createAFPCallbackUrl(FunctionCodeEnum functionCodeEnum) {
        String methodUrl = String.format(TIANCHENG_AFP_CALLBACK_URL, webHttpUrl, functionCodeEnum.getHeadFunctionCode());
        return methodUrl;
    }

    /**
     * 创建天秤授信AFP回调地址
     * @param functionCodeEnum
     * @return
     */
    public String createCreditAFPCallback(FunctionCodeEnum functionCodeEnum) {
        String creditUrl = String.format(TIANCHENG_AFP_CREDIT_CALLBACK_URL, webHttpUrl, functionCodeEnum.getHeadFunctionCode());
        return creditUrl;
    }

    /**
     * 首次授信发送站内信和极光推送
     * @param userId
     * @param creditStatus
     * @param creditAmount
     */
    public void pushSpeedLoanCreditMessage(String userId, boolean creditStatus, BigDecimal creditAmount) {
        if(creditAmount == null ) {
            return;
        }
        UserCreditInfo userCreditInfo = userCreditInfoMapper.selectByUserIdAndType(userId, CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        if(userCreditInfo != null && creditAmount.compareTo(userCreditInfo.getCreditAmount()) < 1) {
            return;
        }
        UserLetterRequestDTO userLetterRequestDTO = new UserLetterRequestDTO();
        userLetterRequestDTO.setToUserId(userId);
        userLetterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        if(userCreditInfo == null) {
            if(!creditStatus) {
                // 授信额度不足通知
                userLetterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.SPEED_LOAN_CREDIT_INADEQUATE);
                userLetterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.SPEED_LOAN_CREDIT_INADEQUATE);
            }else {
                // 授信成功通知
                userLetterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.SPEED_LOAN_CREDIT_RESULT);
                userLetterRequestDTO.setJpushTemplateParamList(Arrays.asList(creditAmount));
                userLetterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.SPEED_LOAN_CREDIT_RESULT);
                userLetterRequestDTO.setLetterTemplateParamList(Arrays.asList(creditAmount));
                // 站内信发布借款按钮添加
                AppButtonDTO appButtonDTO = new AppButtonDTO();
                appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.LOAN);
                appButtonDTO.setLabel(AppButtonDTO.ButtonTypeEnum.LOAN.getDesc());
                userLetterRequestDTO.setLetterButtonList(Arrays.asList(appButtonDTO));
            }
            try {
                userLetterService.pushLetter(userLetterRequestDTO);
                userLetterService.jpush(userLetterRequestDTO);
            } catch (Exception e) {
                log.error("首次授信发送站内信和极光推送异常, userId:{}, e:{}", userId, e);
            }
        }
        if(userCreditInfo != null && creditAmount.compareTo(userCreditInfo.getCreditAmount()) > 0 && creditStatus) {
            // 授信额度提升通知
            userLetterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.SPEED_LOAN_CREDIT_INCREASE);
            userLetterRequestDTO.setJpushTemplateParamList(Arrays.asList(creditAmount));
            userLetterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.SPEED_LOAN_CREDIT_INCREASE);
            userLetterRequestDTO.setLetterTemplateParamList(Arrays.asList(creditAmount));
            try {
                userLetterService.pushLetter(userLetterRequestDTO);
                userLetterService.jpush(userLetterRequestDTO);
            } catch (Exception e) {
                log.error("授信额度提升发送站内信和极光推送异常, userId:{}, e:{}", userId, e);
            }
        }


    }


}
